package com.tangruojie.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tangruojie.converter.UserConverter;
import com.tangruojie.dao.AddressDao;
import com.tangruojie.dao.UserDao;
import com.tangruojie.domain.dto.UserAddressDTO;
import com.tangruojie.domain.entity.Address;
import com.tangruojie.domain.query.PageQuery;
import com.tangruojie.domain.query.UserQuery;
import com.tangruojie.domain.vo.PageVO;
import com.tangruojie.domain.vo.UserAddressVO;
import com.tangruojie.domain.vo.UserVO;
import com.tangruojie.page.PageResult;
import com.tangruojie.page.PageUtils;
import com.tangruojie.service.IUserService;
import com.tangruojie.domain.entity.User;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class UserServiceImpl extends ServiceImpl<UserDao, User> implements IUserService {

    private final UserConverter userConverter;

    private final UserDao userDao;

    private final AddressDao addressDao;

    /**
     * 单表查询
     * 更新用户年龄
     *
     * @param id
     * @param age
     * @return
     */
    @Override
    public boolean updateUserAgeById(Long id, Integer age) {
        User user = getById(id);
        user.setAge(age);
        return updateById(user);
    }

    /**
     * 单表查询
     * 查询用户
     *
     * @param userQuery
     * @return
     */
    @Override
    @Transactional
    public List<UserVO> queryUser(UserQuery userQuery) {
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        /**
         * 条件成立时，才会添加对应条件
         */
        lambdaQueryWrapper
                .like(userQuery.getName() != null, User::getName, userQuery.getName())
                .gt(userQuery.getAgeMin() != null, User::getAge, userQuery.getAgeMin())
                .lt(userQuery.getAgeMax() != null, User::getAge, userQuery.getAgeMax())
                .like(userQuery.getTelephone() != null, User::getTelephone, userQuery.getTelephone());
        return list(lambdaQueryWrapper).stream()
                .map(userConverter::toUserVO)
                .toList();
    }

    /**
     * 单表查询
     * 分页查询用户
     *
     * @param userQuery
     * @return
     */
    @Override
    public PageVO<UserVO> queryUserPage(UserQuery userQuery) {
        /**
         * 分页条件
         */
        Page<User> page = new Page<>(userQuery.getPageNum(), userQuery.getPageSize());
        OrderItem orderItem = new OrderItem();
        orderItem.setColumn(userQuery.getSortProperty()).setAsc(userQuery.getOrder());
        page.addOrder(orderItem);
        /**
         * 查询条件
         */
        List<UserVO> list = lambdaQuery()
                .like(userQuery.getName() != null, User::getName, userQuery.getName())
                .eq(userQuery.getSex() != null, User::getSex, userQuery.getSex())
                .gt(userQuery.getAgeMin() != null, User::getAge, userQuery.getAgeMin())
                .lt(userQuery.getAgeMax() != null, User::getAge, userQuery.getAgeMax())
                .like(userQuery.getTelephone() != null, User::getTelephone, userQuery.getTelephone())
                .page(page)
                .getRecords()
                .stream().map(userConverter::toUserVO).toList();
        PageVO<UserVO> pageVO = new PageVO<>();
        pageVO.setTotal(page.getTotal());
        pageVO.setPages(page.getPages());
        pageVO.setList(list);
        return pageVO;
    }

    /**
     * 多表查询
     *
     * @return
     */
    @Override
    public List<UserAddressVO> selectUserWithAddress() {
        List<UserAddressDTO> userAddressDTOS = userDao.selectUserWithAddress();
        return userAddressDTOS.stream()
                .map(userConverter::toUserAddressVO)
                .toList();
    }

    /**
     * 多表查询
     * 分页查询用户
     *
     * @return
     */
    @Override
    public PageVO<UserAddressVO> selectUserWithAddressPage(PageQuery pageQuery) {
        Page<UserAddressDTO> page = new Page<>(pageQuery.getPageNum(), pageQuery.getPageSize());
        page.addOrder(new OrderItem().setColumn("id").setAsc(true));
        List<UserAddressDTO> userAddressDTOS = userDao.selectUserWithAddressPage(page);
        List<UserAddressVO> list = userAddressDTOS.stream()
                .map(userConverter::toUserAddressVO)
                .toList();
        PageVO<UserAddressVO> objectPageVO = new PageVO<>();
        objectPageVO.setPages(page.getPages());
        objectPageVO.setTotal(page.getTotal());
        objectPageVO.setList(list);
        return objectPageVO;
    }

    /**
     * 多表查询
     *
     * @return
     */
    @Override
    public List<UserAddressVO> getUserWithAddress() {
        /**
         * 查询所有用户
         */
        List<User> users = userDao.selectList(null);
        /**
         * 查询所有地址
         */
        List<Address> addresses = addressDao.selectList(null);
        /**
         * 将地址列表转换成 Map<provinceId, provinceName>，便于快速查找
         */
        Map<Integer, String> collect = addresses.stream()
                .collect(Collectors.toMap(Address::getProvinceId, Address::getProvinceName));
        /**
         * 组装DTO
         */
        List<UserAddressDTO> list = users.stream()
                .map(user -> {
                    UserAddressDTO userAddressDTO = new UserAddressDTO();
                    userAddressDTO.setUserId(user.getId());
                    userAddressDTO.setUserName(user.getName());
                    userAddressDTO.setUserSex(user.getSex());
                    userAddressDTO.setUserPassword(user.getPassword());
                    userAddressDTO.setUserAge(user.getAge());
                    userAddressDTO.setUserTelephone(user.getTelephone());
                    userAddressDTO.setUserTeacher(user.getUserTeacher());
                    userAddressDTO.setUserAddress(collect.get(user.getAddress()));
                    return userAddressDTO;
                }).toList();
        return list.stream()
                .map(userConverter::toUserAddressVO)
                .toList();
    }

    /**
     * 多表查询
     * 分页查询用户
     *
     * @return
     */
    @Override
    public PageResult<UserAddressVO> getUserWithAddressPage(int pageNum, int pageSize) {
        // 1. 查询所有用户
        List<User> users = userDao.selectList(null);

        // 2. 查询所有地址
        List<Address> addresses = addressDao.selectList(null);

        // 3. 地址转 Map<provinceId, provinceName>
        Map<Integer, String> addressMap = addresses.stream()
                .collect(Collectors.toMap(Address::getProvinceId, Address::getProvinceName));

        // 4. 拼装 DTO 列表
        List<UserAddressDTO> allDTOs = users.stream()
                .map(user -> {
                    UserAddressDTO dto = new UserAddressDTO();
                    dto.setUserId(user.getId());
                    dto.setUserName(user.getName());
                    dto.setUserSex(user.getSex());
                    dto.setUserPassword(user.getPassword());
                    dto.setUserAge(user.getAge());
                    dto.setUserTelephone(user.getTelephone());
                    dto.setUserTeacher(user.getUserTeacher());
                    dto.setUserAddress(addressMap.get(user.getAddress()));
                    return dto;
                }).toList();

        // 5. 手动分页 DTO
        PageResult<UserAddressDTO> pagedDTO = PageUtils.paginate(allDTOs, pageNum, pageSize);

        // 6. DTO → VO 转换
        List<UserAddressVO> voList = pagedDTO.getRecords().stream()
                .map(userConverter::toUserAddressVO)
                .toList();

        // 7. 封装返回
        return new PageResult<>(pagedDTO.getTotal(), pageNum, pageSize, voList);
    }


}
